﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#ifndef _UXS_GL_RENDER_BUFFER_H
#define _UXS_GL_RENDER_BUFFER_H

#pragma once

#include "GLStateManager.h"

namespace UX_STL
{
namespace GLShell
{

	//
	// Render Target
	//

	class UX_EXPORT GLRenderTarget : public GLBaseObject
	{
	protected:
		uvec3				_vDimension;
		gl_rt_format::type	_eIFormat;

	public:
		GLRenderTarget(): _vDimension(), _eIFormat(gl_rt_format::_UNKNOWN) {}

		virtual void Attach(GLFrameBuffer *pFBO, gl_fbo_attach::type eAttach, uint uLevel = 0, uint uLayer = 0) = 0;
		virtual bool Create(gl_rt_format::type eFormat, const uvec3 &vDim, uint8 uSamples = 0) = 0;
		
		const uvec3 &		Dimension()			const	{ return _vDimension; }
		gl_rt_format::type	InternalFormat()	const	{ return _eIFormat; }
	};



	//
	// Render Buffer
	//

	class UX_EXPORT GLRenderBuffer : public GLRenderTarget
	{
	public:
		struct GLRenderBufferInfo
		{
			enum EType
			{
				R	= 0,
				G,
				B,
				A,
				DEPTH,
				STENCIL,
				_SIZE,
			};

			typedef static_array< uint, _SIZE >						comsize_array_t;

			uvec2				vDimension;
			comsize_array_t		aCompSize;	// size in bits of RGBA color, depth and stencil components
			uint				uSamples;
			gl_rt_format::type	eIFormat;
			///
			GLRenderBufferInfo():
				uSamples(0), eIFormat(gl_rt_format::_UNKNOWN) {}
		};

	private:
		GLuint		_uID;

	public:
		GLRenderBuffer();
		~GLRenderBuffer();
		
		// GLRenderTarget //
		virtual void Attach(GLFrameBuffer *pFBO, gl_fbo_attach::type eAttach, uint uLevel = 0, uint uLayer = 0);
		virtual bool Create(gl_rt_format::type eFormat, const uvec3 &vDim, uint8 uSamples = 0);
		
		bool  Create(const uvec2 &vDim, gl_rt_format::type eIFormat, uint uSamples = 0);
		bool  Create(const uvec2 &vDim, gl_rt_format::type eIFormat, uint uCoverageSamples, uint uColorSamples);
		void  Destroy();

		bool  AttachToTexture(GLTexture *pTex) const;
		bool  GetInfo(GLRenderBufferInfo &sInfo) const;

		void  Bind()	const;
		void  Unbind()	const;

		GLuint	Id()		const		{ return _uID; }
		GLenum	Target()	const		{ return GL_RENDERBUFFER; }


		static bool s_CheckRenderBufferFunctions();
	};
	

	
//-------------------------- GLRenderBuffer -----------------------//
/*
=================================================
	установить текущий рендербуфер
=================================================
*/
	inline void GLRenderBuffer::Bind() const
	{
		GL_CALL( SMAN()->BindRenderbuffer( _uID ) );
	}
	
/*
=================================================
	установить дефолтовый рендербуфер
=================================================
*/
	inline void GLRenderBuffer::Unbind() const
	{
		GL_CALL( SMAN()->BindRenderbuffer( 0 ) );
	}

//-------------------------------------------------------------------
	
}	// GLShell
}	// UX_STL

#endif	// _UXS_GL_RENDER_BUFFER_H